<template>
  <div class="flex flex-row h-screen">
    <!-- 侧边栏区域 -->
    <div class="sidebar" :class="{ collapsed: isCollapsed }">
      <!-- 缩放按钮 -->
      <div class="p-20px cursor-pointer" @click="toggleSidebar">
        <el-icon :size="20">
          <component :is="isCollapsed ? 'Expand' : 'Fold'" />
        </el-icon>
      </div>
      <!-- 菜单区域 -->
      <el-menu
        :unique-opened="true"
        :default-active="currentBusiness"
        class="menu"
        :collapse="isCollapsed"
      >
        <el-sub-menu
          v-for="(item, index) in table"
          :key="index"
          :index="item.type"
          @click="handleMenuSelect(item.type)"
        >
          <template #title>
            <el-icon v-if="isCollapsed">
              <img
                :src="getAssets(item.type + '.png')"
                alt="icon"
                class="w-0.8 h-0.8"
              />
            </el-icon>
            <span v-if="!isCollapsed">{{ item.label }}</span>
          </template>
          <el-menu-item
            v-for="(question, qIndex) in commonQuestions[item.type].questions"
            :key="qIndex"
            @click="handlck(question)"
            :index="`${item.type}-${qIndex}`"
            :data-content="question"
          >
            <span>{{ truncateText(question, 15) }}</span>
            <!-- 截断显示 -->
          </el-menu-item>
        </el-sub-menu>
      </el-menu>
    </div>
    <!-- 问答区 -->
    <div class="flex flex-col flex-1 p-10px w-80%">
      <div
        ref="messageContainer"
        class="h-90vh overflow-auto"
        style="scroll-behavior: smooth"
      >
        <div
          v-for="(message, index) in messages[currentBusiness]"
          :key="index"
          class="mb-2"
        >
          <div
            :class="[
              'flex',
              message.role === 'user' ? 'justify-end' : 'justify-start',
            ]"
          >
            <div class="max-w-70%">
              <div
                :class="
                  message.role === 'user'
                    ? 'bg-blue-500 text-white'
                    : 'bg-gray-300 text-black'
                "
                class="p-0.5 rounded-10px"
              >
                <div v-if="message.think && message.role !== 'user'">
                  <div class="think-box">
                    {{ message.think }}
                  </div>
                  <div class="text-content">
                    {{ message.content }}
                  </div>
                </div>
                <div v-else>
                  {{ message.content }}
                </div>
              </div>
            </div>
          </div>
        </div>
        <!-- 在消息循环后添加加载动画 -->
        <div v-if="isLoading" class="flex justify-start mb-2">
          <div class="max-w-70%">
            <div class="bg-gray-300 rounded-10px">
              <div class="flex items-center px-1 py-0.5">
                <div class="dot-flashing"></div>
              </div>
            </div>
          </div>
        </div>
      </div>
      <div class="relative bottom-0 right-0 flex w-100% items-center">
        <form
          @submit.prevent="handlck(textareaContent)"
          class="flex w-100% justify-center"
        >
          <div class="frominput w-50%">
            <!-- <el-input
              v-model="textareaContent"
              type="textarea"
              :autosize="{ minRows: 2, maxRows: 3 }"
              class="m-10px"
            /> -->
            <textarea
              v-model="textareaContent"
              class="custom-textarea"
              @keydown.space.prevent
              @keydown.enter.prevent="handlck(textareaContent)"
              @input="handleTextInput"
            ></textarea>
            <button class="btn" type="submit">
              <img :src="getAssets('push.png')" class="w-0.8 h-0.8" />
            </button>
            <!-- <img
              type="submit"
              :src="getAssets('push.png')"
              class="w-0.8 h-0.8"
            /> -->
          </div>
        </form>
      </div>
    </div>
  </div>
</template>
<script lang="ts" setup>
import { getAssets } from "@/utils";
import { commonQuestions } from "@/utils/faq";

const handleTextInput = (e: Event) => {
  const target = e.target as HTMLTextAreaElement;
  textareaContent.value = target.value.replace(/[\s　]/g, "");
};
interface Message {
  id: string;
  role: string;
  content: string;
  think?: string;
}
const isLoading = ref(false);
type BusinessType = "enforce" | "against" | "dispose" | "vehicle" | "driving";

const table = ref([
  { label: "处警执法", type: "enforce" as BusinessType },
  { label: "违法处理", type: "against" as BusinessType },
  { label: "事故处理", type: "dispose" as BusinessType },
  { label: "车管业务", type: "vehicle" as BusinessType },
  { label: "驾管业务", type: "driving" as BusinessType },
]);

const messages = ref<Record<BusinessType, Message[]>>({
  enforce: [],
  against: [],
  dispose: [],
  vehicle: [],
  driving: [],
});

const currentBusiness = ref<BusinessType>("enforce");
const truncateText = (text: string, maxLength: number) => {
  return text.length > maxLength ? text.slice(0, maxLength) + "..." : text;
};
const handleMenuSelect = (type: string) => {
  currentBusiness.value = type as BusinessType;

  scrollToBottom();
};

const messageContainer = ref<HTMLElement | null>(null);
const scrollToBottom = () => {
  nextTick(() => {
    if (messageContainer.value) {
      messageContainer.value.scrollTo({
        top: messageContainer.value.scrollHeight,
        behavior: "smooth",
      });
    }
  });
};
const textareaContent = ref("");

const isCollapsed = ref(false);
const toggleSidebar = () => {
  isCollapsed.value = !isCollapsed.value;
};

// 匹配方法
// const matchCommonQuestion = (
//   input: string
// ): { answer: string; think?: string } | null => {
//   const cleanInput = input.replace(/[\s.,?。，？]/g, "").toLowerCase();

//   for (const category of Object.values(commonQuestions)) {
//     for (const question of category.questions) {
//       const cleanQ = question.replace(/[\s.,?。，？]/g, "").toLowerCase();
//       if (cleanInput.includes(cleanQ) || cleanQ.includes(cleanInput)) {
//         return {
//           answer: category.answer.join("\n"), // 将数组转换为字符串
//           think: category.think?.join("\n"), // 处理思考内容
//         };
//       }
//     }
//   }
//   return null;
// };

const handlck = async (question: string) => {
  if (isLoading.value) return;
  if (!question.trim()) return;
  messages.value[currentBusiness.value].push({
    id: Date.now().toString(),
    role: "user",
    content: question,
  });
  // const preset = matchCommonQuestion(question);
  // if (preset) {
  //   // 添加带有思考过程的消息
  //   messages.value[currentBusiness.value].push({
  //     id: Date.now().toString(),
  //     role: "assistant",
  //     content: preset.answer,
  //     think: preset.think, // 添加思考内容
  //   });
  //   scrollToBottom();
  //   return;
  // }
  textareaContent.value = "";
  scrollToBottom();
  isLoading.value = true;
  try {
    const chat_id = "1f785cc6ff2211efbb310242ac120002";
    const api_key = "ragflow-c3NDc3MjAwMDllNzExZjA4MjE5MDI0Mm";
    const url = `http://65.72.0.10/api/v1/chats_openai/${chat_id}/chat/completions`;

    const response = await fetch(url, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        Authorization: `Bearer ${api_key}`,
      },
      body: JSON.stringify({
        model: "deepseel-r:70b",
        messages: [{ role: "user", content: question }],
        stream: true,
      }),
    });

    if (response.body) {
      const reader = response.body.getReader();
      let result = "";

      let buffer = "";

      while (true) {
        const { done, value } = await reader.read();
        if (done) break;
        buffer += new TextDecoder().decode(value);
      }

      const lines = buffer.split("\n");
      for (const line of lines) {
        if (!line.trim()) continue;
        try {
          if (line.startsWith("data:")) {
            const dataStr = line.slice(5);
            if (dataStr === "[DONE]") {
              continue;
            }
            const data = JSON.parse(dataStr);
            const content = data.choices?.[0]?.delta?.content;
            if (content) {
              result += content;
            }
          } else {
            const data = JSON.parse(line);
            const content = data.choices?.[0]?.delta?.content;
            if (content) {
              result += content;
            }
          }
        } catch (err) {
          console.error("解析失败:", err);
        }
      }
      messages.value[currentBusiness.value].push({
        id: Date.now().toString(),
        role: "assistant",
        content: "",
        think: "",
      });
      isLoading.value = false;
      processAIMessage(result);
    }
  } catch (err) {
    console.error("请求失败:", err);
    isLoading.value = false;
    messages.value[currentBusiness.value].push({
      id: Date.now().toString(),
      role: "assistant",
      content: "请求失败，请重试",
    });
  }
};
const processAIMessage = (data: string) => {
  if (!hasThinkTag(data)) return;
  const lastMsgIndex = messages.value[currentBusiness.value].length - 1;
  if (messages.value[currentBusiness.value][lastMsgIndex].role !== "assistant")
    return;
  const thinkContent = getThinkContent(data);
  const regularContent = getRegularContent(data);
  messages.value[currentBusiness.value][lastMsgIndex].think = "";
  messages.value[currentBusiness.value][lastMsgIndex].content = "";
  const fillContent = (type: "think" | "content", text: string) => {
    let index = 0;
    const writer = () => {
      if (index < text.length) {
        messages.value[currentBusiness.value][lastMsgIndex][type] +=
          text[index];
        index++;
        scrollToBottom();
        setTimeout(writer, 50);
      } else if (type === "think") {
        fillContent("content", regularContent);
      }
    };
    writer();
  };
  fillContent("think", thinkContent);
};
const hasThinkTag = (content: string) => {
  return /<think>[\s\S]*<\/think>/.test(content);
};
const getThinkContent = (content: string) => {
  const match = content.match(/<think>([\s\S]*)<\/think>/);
  return match ? match[1] : "";
};
const getRegularContent = (content: string) => {
  return content.replace(/<think>[\s\S]*<\/think>/g, "").trim();
};
</script>

<style lang="less" scoped>
.btn {
  background: none;
  border: none;
}
@media (max-width: 768px) {
  input {
    max-width: 100%;
    font-size: 16px;
  }
}
input {
  -webkit-box-shadow: none;
  -moz-box-shadow: none;
  box-shadow: none;
  -ms-word-break: break-all;
  word-break: break-all;
}
.custom-textarea {
  white-space: pre-line;
  word-wrap: break-word;
  overflow-wrap: break-word;
  width: 100%;
  min-height: 40px;
  max-height: 120px;
  padding: 8px 12px;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen,
    Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
  font-size: 14px;
  line-height: 1.5;
  color: #333;
  border: none;
  border-radius: 4px;
  transition: all 0.3s ease;
  white-space: nowrap;
  word-break: keep-all;
  overflow-x: auto;

  @supports (-moz-appearance: none) {
    text-transform: capitalize;
  }

  scrollbar-width: none;
  &::-webkit-scrollbar {
    display: none;
  }

  &:focus {
    outline: none;
    border-bottom-color: #007bff;
    box-shadow: none;
  }

  // 优化文本换行
  white-space: pre-wrap;
  word-wrap: break-word;
  overflow-wrap: anywhere;
}
.frominput {
  display: flex;
  flex-direction: row;
  align-items: center;
  border: 1px solid #baccf1;
  padding: 0.05rem 0.1rem;
  border-radius: 0.1rem;
  input {
    border: none;
    width: 100%;
    font-size: 0.2rem;
    white-space: pre-wrap;
    word-break: break-word;
    overflow-wrap: break-word;
    min-height: 1.2em;
    line-height: 1.2;
    resize: vertical;

    &:focus {
      outline: none;
      border-bottom-color: #007bff;
      box-shadow: none;
    }
  }
}
.item {
  border: 1px solid #e5e7eb;
  border-radius: 8px;
  transition: all 0.2s ease;
  margin: 8px 0;
  padding: 12px;
  background-color: white;

  &:hover {
    border-color: #409eff;
    box-shadow: 0 2px 8px rgba(64, 158, 255, 0.15);
  }
}

.dot-flashing {
  position: relative;
  width: 10px;
  height: 10px;
  border-radius: 5px;
  background-color: #409eff;
  color: #409eff;
  animation: dotFlashing 1s infinite linear alternate;
  animation-delay: 0.5s;

  &::before,
  &::after {
    content: "";
    display: inline-block;
    position: absolute;
    top: 0;
  }

  &::before {
    left: -15px;
    width: 10px;
    height: 10px;
    border-radius: 5px;
    background-color: #409eff;
    color: #409eff;
    animation: dotFlashing 1s infinite alternate;
    animation-delay: 0s;
  }

  &::after {
    left: 15px;
    width: 10px;
    height: 10px;
    border-radius: 5px;
    background-color: #409eff;
    color: #409eff;
    animation: dotFlashing 1s infinite alternate;
    animation-delay: 1s;
  }
}

@keyframes dotFlashing {
  0% {
    transform: scale(1);
    opacity: 0.5;
  }
  50%,
  100% {
    transform: scale(0.6);
    opacity: 1;
  }
}

.text-content {
  border-bottom: 1px dashed rgba(0, 0, 0, 0.1);
  padding-bottom: 8px;
  margin-bottom: 8px;
}

.think-content {
  color: #4b5563;
  font-size: 0.9em;
}

.sidebar {
  width: 320px; /* 增加侧边栏宽度 */
  height: 100vh;
  border-right: 1px solid #e5e7eb;
  display: flex;
  flex-direction: column;
  background-color: white;
  box-shadow: 2px 0 8px rgba(0, 0, 0, 0.05);
  transition: width 0.3s ease;
  // overflow-y: auto; /* 添加垂直滚动条 */

  &.collapsed {
    width: 64px;
  }
}

.menu {
  border-right: none;
  background-color: transparent;
  flex: 1; /* 使菜单区域占据剩余空间 */
  overflow-y: auto; /* 添加垂直滚动条 */

  :deep(.el-sub-menu__title) {
    padding-left: 16px !important;
  }

  :deep(.el-menu-item) {
    position: relative;
    // max-width: 240px; /* 控制最大宽度 */

    span {
      display: inline-block;
      max-width: 100%;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }

    /* 添加悬浮提示 */
    &:hover::after {
      content: attr(data-content);
      position: absolute;
      left: 0;
      top: 100%;
      background: #fff;
      border: 1px solid #ebeef5;
      padding: 8px;
      border-radius: 4px;
      box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
      z-index: 2000;
      max-width: 400px;
      white-space: normal;
      display: none; /* 默认隐藏 */
    }

    &:hover:hover::after {
      display: block; /* 双重悬停触发显示 */
    }
  }
}

.yewu {
  height: auto;
  padding: 16px;
  width: 100%;
  border-bottom: 1px solid #e5e7eb;
}

.faq-section {
  flex: 1;
  padding: 16px;
  overflow-y: auto;
  background-color: #f9fafb;
}

.box {
  border: 1px solid #e5e7eb;
  border-radius: 12px;
  margin: 8px 0;
  padding: 16px;
  transition: all 0.3s ease;
  background-color: white;
  cursor: pointer;

  &:hover {
    border-color: #409eff;
    transform: translateY(-2px);
    box-shadow: 0 4px 12px rgba(64, 158, 255, 0.15);
  }

  &.selected-box {
    border: 2px solid #409eff;
    background-color: rgba(64, 158, 255, 0.05);
    box-shadow: 0 4px 12px rgba(64, 158, 255, 0.2);
  }
}

.think-box {
  background: rgba(0, 0, 0, 0.03);
  border-left: 3px solid #409eff;
  padding: 12px;
  border-radius: 4px;
  margin-bottom: 12px;
}
.h-90vh {
  scrollbar-width: none;
  -ms-overflow-style: none;

  &::-webkit-scrollbar {
    display: none;
  }
  scrollbar-width: none;
  -ms-overflow-style: none;
  &::-webkit-scrollbar {
    display: none;
  }
}

* {
  box-sizing: border-box;
}

body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen,
    Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
  color: #1f2937;
}

.el-textarea {
  border-radius: 8px;
  border: 1px solid #e5e7eb;
  transition: all 0.2s ease;

  &:focus {
    border-color: #409eff;
    box-shadow: 0 0 0 3px rgba(64, 158, 255, 0.1);
  }
}

.el-icon {
  transition: all 0.2s ease;
  color: #6b7280;

  &:hover {
    color: #409eff;
    transform: scale(1.1);
  }
}
::v-deep .el-input__wrapper {
  background: transparent;
  font-size: 20px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.2);
  padding: 0 10px;
  width: 100%;
  box-shadow: none;
  border: none;
  &:focus {
    outline: none;
    border-bottom-color: #007bff;
    box-shadow: none;
  }
  .el-input__inner {
    color: white;
  }
}
</style>